using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ProductService.Domain.Models;
using ProductService.Domain.Repositories;
using ProductService.Application.Services;
using SharedKernel.Infrastructure.EventBus;
using SharedKernel.Domain.Events;
using Microsoft.EntityFrameworkCore;

namespace ProductService.Application.Services
{
    /// <summary>
    /// 商品应用服务实现
    /// </summary>
    public class ProductAppService : IProductAppService
    {
        private readonly IProductRepository _productRepository;
        private readonly IEventBus _eventBus;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="productRepository">商品仓储</param>
        /// <param name="eventBus">事件总线</param>
        public ProductAppService(IProductRepository productRepository, IEventBus eventBus)
        {
            _productRepository = productRepository;
            _eventBus = eventBus;
        }

        /// <summary>
        /// 获取商品
        /// </summary>
        /// <param name="id">商品ID</param>
        /// <returns>商品实体</returns>
        public async Task<Product> GetProductAsync(Guid id)
        {
            return await _productRepository.SingleAsync(id);
        }
         
        /// <summary>
        /// 根据分类获取商品
        /// </summary>
        /// <param name="category">商品分类</param>
        /// <returns>商品列表</returns>
        public async Task<List<Product>> GetProductsByCategoryAsync(string category)
        {
            return await _productRepository.GetByCategoryAsync(category);
        }

        /// <summary>
        /// 创建商品
        /// </summary>
        /// <param name="name">商品名称</param>
        /// <param name="description">商品描述</param>
        /// <param name="price">商品价格</param>
        /// <param name="stock">商品库存</param>
        /// <param name="category">商品分类</param>
        /// <returns>创建的商品ID</returns>
        public async Task<Guid> CreateProductAsync(string name, string description, decimal price, int stock, string category)
        {
            var product = Product.Create(name, description, price, stock, category);
            await _productRepository.InsertAsync(product);

            // 发布领域事件
            foreach (var domainEvent in product.DomainEvents)
            {
                if (domainEvent is DomainEvent concreteEvent)
                {
                    await _eventBus.PublishAsync(concreteEvent);
                }
            }

            product.ClearDomainEvents();
            return product.Id;
        }

        /// <summary>
        /// 更新商品
        /// </summary>
        /// <param name="id">商品ID</param>
        /// <param name="name">商品名称（可选）</param>
        /// <param name="description">商品描述（可选）</param>
        /// <param name="price">商品价格（可选）</param>
        /// <param name="category">商品分类（可选）</param>
        public async Task UpdateProductAsync(Guid id, string name = null, string description = null, decimal? price = null, string category = null)
        {
            var product = await _productRepository.SingleAsync(id);
            if (product == null)
                throw new KeyNotFoundException($"未找到ID为{{id}}的商品");

            product.Update(name, description, price, category);
            await _productRepository.UpdateAsync(product);

            // 发布领域事件
            foreach (var domainEvent in product.DomainEvents)
            {
                if (domainEvent is DomainEvent concreteEvent)
                {
                    await _eventBus.PublishAsync(concreteEvent);
                }
            }

            product.ClearDomainEvents();
        }

        /// <summary>
        /// 删除商品
        /// </summary>
        /// <param name="id">商品ID</param>
        public async Task DeleteProductAsync(Guid id)
        {
            var product = await _productRepository.SingleAsync(id);
            if (product == null)
                throw new KeyNotFoundException($"未找到ID为{{id}}的商品");

            await _productRepository.DeleteAsync(product);
        }

        /// <summary>
        /// 减少商品库存
        /// </summary>
        /// <param name="id">商品ID</param>
        /// <param name="quantity">减少数量</param>
        public async Task ReduceStockAsync(Guid id, int quantity)
        {
            var product = await _productRepository.SingleAsync(id);
            if (product == null)
                throw new KeyNotFoundException($"未找到ID为{{id}}的商品");

            product.ReduceStock(quantity);
            await _productRepository.UpdateAsync(product);

            // 发布领域事件
            foreach (var domainEvent in product.DomainEvents)
            {
                if (domainEvent is DomainEvent concreteEvent)
                {
                    await _eventBus.PublishAsync(concreteEvent);
                }
            }

            product.ClearDomainEvents();
        }

        /// <summary>
        /// 增加商品库存
        /// </summary>
        /// <param name="id">商品ID</param>
        /// <param name="quantity">增加数量</param>
        public async Task IncreaseStockAsync(Guid id, int quantity)
        {
            var product = await _productRepository.SingleAsync(id);
            if (product == null)
                throw new KeyNotFoundException($"未找到ID为{{id}}的商品");

            product.IncreaseStock(quantity);
            await _productRepository.UpdateAsync(product);

            // 发布领域事件
            foreach (var domainEvent in product.DomainEvents)
            {
                if (domainEvent is DomainEvent concreteEvent)
                {
                    await _eventBus.PublishAsync(concreteEvent);
                }
            }

            product.ClearDomainEvents();
        }

        /// <summary>
        /// 搜索商品
        /// </summary>
        /// <param name="keyword">搜索关键词</param>
        /// <returns>商品列表</returns>
        public async Task<List<Product>> SearchProductsAsync(string keyword)
        {
            return await _productRepository.SearchAsync(keyword);
        }
    }
}